import XLog from "../libs/XLog";
import DataCenter from "./DataCenter";
// import SerialPortLoop from "../libs/SerialPortController";
// import SerialPortMeter from "../libs/SerialMeterController";
import { LightMode, RS_Device_Type, Default_Request_List, Loop_Device_Base } from "../libs/SerialCommon";
import { DeviceEventEmitter } from "react-native";
import SerialPorts from "../libs/SerialPortClient";
import { MeterConfig, ProductID, SerialConfig, ValidType } from "./LogicConstant";

export default class SerialPortManager{
    static serialEventHandler = {};
    static setLightArr = {};
    static resendListener = null;
    static queryMeterList = [];
    static deviceMap = {};
    static serialController = {};

    //product：loop meter
    static async createDevice(product, deviceList, successCallback, failCallback){
        console.log("createDevice: ",product, deviceList);
        if(!deviceList) {
            return;
        }
        let fail = 0;
        let existDevices = this.serialController[product]||{};
        if(!(deviceList instanceof Array)){
            deviceList = [deviceList];
        }
        for(var device of deviceList){
            try{
                if(existDevices[device.index]){
                    await SerialPorts.removeClient(existDevices[device.index], false);//替换，非强制删除底层设备，因为同一个设备可能对应多个client
                }
                let deviceHandler = await SerialPorts.openClient(device.id, device.index, device.key, device.type, device.address, device.option, device.interface);
                deviceHandler.on('error', function(msg) {
                    XLog.e('serial.event.error', msg);
                });
                deviceHandler.on('message', function(msg) {
                    XLog.e('serial.event.message', msg);
                    SerialPortManager.dispatchSerialEvent(msg);
                });
                deviceHandler.on('timeout', function(msg) {
                    XLog.i('serial.event.timeout' + JSON.stringify(msg));
                    SerialPortManager.dispatchSerialEvent(msg);
                });
                if(product == ProductID.LOOP) {
                    this.setLightArr[device.index] = [];
                }
                
                existDevices[device.index] = deviceHandler;
            }catch(error) {
                XLog.e("createAllDevice exception：" + error?.message + "|" + JSON.stringify(device));
                fail += 1;
            }
        }
        this.serialController[product] = existDevices;
        if(successCallback && fail == 0){
            successCallback(deviceList);
        }
        if(failCallback && fail > 0){
            failCallback(deviceList);
        }
    }

    static async removeAllDevice(product){
        let products = product ? (this.serialController[product] ? [this.serialController[product]] : []) : Object.values(this.serialController||{});
        
        for(let prod of products||[]) {
            for(var device of Object.values(prod)){
                await SerialPorts.removeClient(device, true);//强制清空底层设备
            }
        }
        if(product){
            delete this.serialController[product];
        } else {
            this.serialController = {};
        }        
    }

    static async removeProductDevice(product, index) {
        if(!product) {
            return;
        }
        let device = (this.serialController[product] ? this.serialController[product]?.[index] : null);
        
        if(device) {
            await SerialPorts.removeClient(device, true);//强制清空底层设备
        }
    }

    static addSerialEvent(event, callback){
        let listeners = this.serialEventHandler[event] || new Set();
        listeners.add(callback);
        this.serialEventHandler[event] = listeners;
    }

    static removeSerialEvent(event, callback) {
        let listeners = this.serialEventHandler[event]
        if(listeners) {
            return listeners.delete(callback);
        }
        return false;
    }

    static dispatchSerialEvent(data) {
        let listeners = this.serialEventHandler[data.event];
        if(listeners) {
            listeners.forEach(function(listener) {
                listener(data);
            });
        } else {
            XLog.e("no serial event handler");
        }
    }

    static sendLoopControllerRequest(message, index){
        let loop_product = this.serialController[ProductID.LOOP];
        if(loop_product?.[index]){
            loop_product[index].setRequestList(message);
        }
    }

    static controlLight(loopNumber, light){
        let loop_product = this.serialController[ProductID.LOOP];
        let loopControllerNumber = Math.ceil(loopNumber / Loop_Device_Base);
        let rem = loopNumber % Loop_Device_Base;
        if(loop_product?.[loopControllerNumber]){
            this.setLightArr[loopControllerNumber].push({"lamp": rem, "valid": ValidType.VALID, "light": light});
        }
    }

    static controlLightEnd(){
        let loop_product = this.serialController[ProductID.LOOP];
        for(let loopControllerNumber of Object.keys(loop_product||{})) {
            if(this.setLightArr[loopControllerNumber]?.length > 0 ) 
            {
                loop_product[loopControllerNumber]?.setRequestList({"event": "setLampLight", "data": this.setLightArr[loopControllerNumber]});
                this.setLightArr[loopControllerNumber] = [];
            }
        }
    }

    static setLightMode(mode){
        let loop_product = this.serialController[ProductID.LOOP];
        for(let loopDevices of Object.values(loop_product||{})) {
            loopDevices?.deviceHandler.setLightMode(mode);
        }
    }

    static getLightMode(){
        console.log("getLightMode", this.serialController);
        let loop_product = Object.values(this.serialController[ProductID.LOOP]||{});
        console.log("getLightMode: ", loop_product, loop_product[0]);
        return loop_product && loop_product.length > 0 ? loop_product[0].deviceHandler.getLightMode() : LightMode.POSITIVE_MODE;
    }
    
    static sendMeterRequest(index){
        let mete_products = this.serialController[ProductID.SMART];
        if(mete_products?.[index] && DataCenter.meterConfigList?.length > 0) {
            let requestList = [...DataCenter.meterConfigList];
            console.log("Default_Request_List: ", requestList);
            mete_products?.[index].setRequestList(requestList);
        }
    }
    
}